package top.infopub.job.cap.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.infopub.enums.cap.PayIntDetTypeEnum;
import top.infopub.enums.cap.PayIntModeEnum;
import top.infopub.generic.GenericDao;
import top.infopub.generic.GenericServiceImpl;
import top.infopub.job.cap.dao.PayInterestDao;
import top.infopub.job.cap.dao.PayInterestDetailDao;
import top.infopub.job.cap.domain.FinReimAmtDomain;
import top.infopub.job.cap.domain.LoanFinAmtDomain;
import top.infopub.job.cap.domain.ToDoPayIntDomain;
import top.infopub.job.cap.service.PayInterestService;
import top.infopub.job.flow.service.OAFlowService;
import top.infopub.job.util.DateUtils;
import top.infopub.model.cap.PayInterest;
import top.infopub.model.cap.PayInterestDetail;
import top.infopub.util.IdFactory;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class PayInterestServiceImpl extends GenericServiceImpl<PayInterest, String> implements
		PayInterestService {
	private static final Logger log = LoggerFactory.getLogger(PayInterestServiceImpl.class);

	@Autowired
	private PayInterestDao payInterestDao;

	@Autowired
	private PayInterestDetailDao payInterestDetailDao;

	@Autowired
	private OAFlowService oaFlowService;

	private static String TABLE_NAME = "CAP_PAY_INTEREST";
	
	@Override
	public GenericDao<PayInterest, String> getDao() {
		return payInterestDao;
	}

	@Override
	@Transactional
	public void sendOaPayIntToDo() throws Exception {
		/**
		 * 1.查询周期内的借款合同
		 * 2.根据借款合同中的proCode和金融机构ID查询融资付息上次最大日期
		 *   1).如果按天执行，需要判断付息周期(月，季度，半年等)，不满足的排除
		 *   2).如果是每月定时执行，月数据必须处理，其他周期数据不满足排除
		 *   3).融资付息最大日期需要主表关联子表根据2中的条件进行查询
		 * 3.查询2中的最大日期为空，借款合同初始日期为起始日期，最大日期不为空，最大日期+1为起始日期
		 * 4.截止日期按周期计算，周期天数需求需确定(需确定是否按自然月，非自然月需确定月天数-多少天为一月)
		 * 5.查询周期内的还款计划，计划内有还款需要走第二种情况的付息逻辑(具体参考付息需求)
		 * 6.查询周期内的放款数据，周期内有放款需要走第三种情况的付息逻辑(具体参考付息需求)
		 */
		Date startDate = null;
		Date endDate = null;
		//获取当前日期
		Calendar now = Calendar.getInstance();
		int day = now.get(Calendar.DATE);
		if (day > 20) {
			//如果当前日期大于20号，设置起始时间在当月21号，结束时间为次月20号
			now.set(Calendar.DATE, 21);
			startDate = now.getTime();
			now.add(Calendar.MONTH, 1);
			now.set(Calendar.DATE, 20);
			endDate = now.getTime();
		} else {
			//如果当前日期小于等于20号，起始日期为上月21号，结束日期为当月20号
			now.set(Calendar.DATE, 20);
			endDate = now.getTime();
			now.add(Calendar.MONTH, -1);
			now.set(Calendar.DATE, 20);
			startDate = now.getTime();
		}
		//查询出待发送待办的数据
		List<ToDoPayIntDomain> toDoList = payInterestDao.queryToDoPayInt(startDate, endDate);
		log.info("查询到的待处理记录数量：{}", toDoList.size());
		if (toDoList != null && toDoList.size() > 0) {
			for (ToDoPayIntDomain tdpi : toDoList) {
				if (tdpi == null) continue;
				//融资付息主表数据
				PayInterest payInterest = new PayInterest();
				payInterest.setProCode(tdpi.getProCode());
				payInterest.setCodes(IdFactory.getUUIDUpper());
				payInterest.setPaymentStatus("0");
				//设置指定人员--待确定
				payInterest.setAddBy(tdpi.getAddBy());
				payInterest.setAddTime(new Date());
				payInterest.setUptBy(tdpi.getAddBy());
				payInterest.setUptTime(new Date());
				payInterest.setFinOrgId(tdpi.getFinOrgId());

				//融资付息子表数据
				List<PayInterestDetail> detailList = new ArrayList<>();
				if (StringUtils.equals(PayIntModeEnum.PAY_INT_MODE1.getCode(), tdpi.getPayIntMod())) {
					//月
					//重设起始时间
					startDate = resetStartDate(startDate, tdpi.getBorrowDate());
					endDate = resetEndDate(endDate, tdpi.getBorrowExpireDate());
					//检查当月是否已经发送过待办
					int count = payInterestDetailDao.queryCountByIntDate(startDate, endDate);
					if (count > 0) {
						log.info(String.format("融资付息待办已发送，proCode：%s，finOrgId：%s，startDate：%s，endDate：%s", tdpi.getProCode(), tdpi.getFinOrgId(), DateUtils.dateParseShortString(startDate), DateUtils.dateParseShortString(endDate)));
						continue;
					}
					//查询历史放款总金额
					BigDecimal hisLoanFinSumAmt = payInterestDao.hisLoanFinSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
					if (hisLoanFinSumAmt == null) hisLoanFinSumAmt = new BigDecimal(0);
					//查询历史还款总金额
					BigDecimal hisFinReimSumAmt = payInterestDao.hisFinReimSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
					if (hisFinReimSumAmt == null) hisFinReimSumAmt = new BigDecimal(0);
					//贷款余额
					BigDecimal loanAmt = hisLoanFinSumAmt.subtract(hisFinReimSumAmt);
					//类型
					String types = PayIntDetTypeEnum.PAY_INT_DET_TYPE1.getCode();
					//付息金额-子表总和
					BigDecimal payIntAmt = new BigDecimal(0);
					//查询区间内是否有还款--startDate-endDate之间
					List<FinReimAmtDomain> finReimAmtList = payInterestDao.queryFinReimList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
					//查询区间内是否有放款--startDate-endDate之间
					List<LoanFinAmtDomain> loanFinAmtList = payInterestDao.queryLoanFinList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
					//处理还款记录
					if (finReimAmtList != null && finReimAmtList.size() > 0) {
						for (FinReimAmtDomain frad : finReimAmtList) {
							if (frad == null) continue;
							//根据还款日期计算截止时间
							//还款日期-起始日期=该段时间计息时间
							int days = DateUtils.sub(startDate, frad.getFinReimDate()) + 1;
							if (days <= 0) continue;
							//计划付息金额
							BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
							payIntAmt = payIntAmt.add(planPayIntAmt);
							PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, frad.getFinReimDate(), days, planPayIntAmt);
							detail.setTypes(types);
							detailList.add(detail);
							//重置起始日期
							startDate = DateUtils.add(frad.getFinReimDate(), Calendar.DATE, 1);
							//重置贷款余额
							loanAmt = loanAmt.subtract(frad.getFinReimAmt());
							types = PayIntDetTypeEnum.PAY_INT_DET_TYPE2.getCode();
						}
					}
					//计息天数
					int days = DateUtils.sub(startDate, endDate) + 1;
					if (days <= 0) continue;
					//计划付息金额=贷款余额*利率*计息天数/360
					BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
					payIntAmt = payIntAmt.add(planPayIntAmt);
					PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, endDate, days, planPayIntAmt);
					detail.setTypes(types);
					detailList.add(detail);
					//处理放款记录
					if (loanFinAmtList != null && loanFinAmtList.size() > 0) {
						for (LoanFinAmtDomain lfad : loanFinAmtList) {
							if (lfad == null) continue;
							PayInterestDetail pid = setDetailData(tdpi, hisLoanFinSumAmt, null, null, null, null, null);
							pid.setTypes(PayIntDetTypeEnum.PAY_INT_DET_TYPE3.getCode());
							detailList.add(pid);
						}
					}
					//新增主表数据
					payInterest.setPayIntAmt(payIntAmt);
					payInterestDao.insertSelective(payInterest);
					//新增子表数据
					for (PayInterestDetail tmpDetail : detailList) {
						if (tmpDetail == null) continue;
						tmpDetail.setPayInterestId(payInterest.getId());
						payInterestDetailDao.insertSelective(tmpDetail);
					}
					//发送OA待办
					String oaId = oaFlowService.sendOAToDo(tdpi.getProName(), tdpi.getAddBy(), tdpi.getAddBy(), TABLE_NAME, payInterest.getId(), tdpi.getProCode());
					payInterest.setOaId(oaId);
					payInterestDao.updateByIdSelective(payInterest);
				} else if (StringUtils.equals(PayIntModeEnum.PAY_INT_MODE2.getCode(), tdpi.getPayIntMod())) {
					//季
					Date maxDate = payInterestDao.queryMaxEndDate(tdpi.getProCode(), tdpi.getFinOrgId());
					if (maxDate != null) {
						tdpi.setBorrowDate(maxDate);
					}
					//判断时间是否满足季度3个月
					boolean isSend = checkMonth(tdpi.getBorrowDate(), endDate, 3);
					//判断截止日是否小于endDate，如果小于默认结清
					int tmpDay = DateUtils.sub(tdpi.getBorrowExpireDate(), endDate);
					if (tmpDay >= 0 || isSend) {
						//重设起始时间
						startDate = resetStartDate(startDate, tdpi.getBorrowDate());
						endDate = resetEndDate(endDate, tdpi.getBorrowExpireDate());
						//检查当月是否已经发送过待办
						int count = payInterestDetailDao.queryCountByIntDate(startDate, endDate);
						if (count > 0) {
							log.info(String.format("融资付息待办已发送，proCode：%s，finOrgId：%s，startDate：%s，endDate：%s", tdpi.getProCode(), tdpi.getFinOrgId(), DateUtils.dateParseShortString(startDate), DateUtils.dateParseShortString(endDate)));
							continue;
						}
						//查询历史放款总金额
						BigDecimal hisLoanFinSumAmt = payInterestDao.hisLoanFinSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisLoanFinSumAmt == null) hisLoanFinSumAmt = new BigDecimal(0);
						//查询历史还款总金额
						BigDecimal hisFinReimSumAmt = payInterestDao.hisFinReimSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisFinReimSumAmt == null) hisFinReimSumAmt = new BigDecimal(0);
						//贷款余额
						BigDecimal loanAmt = hisLoanFinSumAmt.subtract(hisFinReimSumAmt);
						//类型
						String types = PayIntDetTypeEnum.PAY_INT_DET_TYPE1.getCode();
						//付息金额-子表总和
						BigDecimal payIntAmt = new BigDecimal(0);
						//查询区间内是否有还款--startDate-endDate之间
						List<FinReimAmtDomain> finReimAmtList = payInterestDao.queryFinReimList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//查询区间内是否有放款--startDate-endDate之间
						List<LoanFinAmtDomain> loanFinAmtList = payInterestDao.queryLoanFinList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//处理还款记录
						if (finReimAmtList != null && finReimAmtList.size() > 0) {
							for (FinReimAmtDomain frad : finReimAmtList) {
								if (frad == null) continue;
								//根据还款日期计算截止时间
								//还款日期-起始日期=该段时间计息时间
								int days = DateUtils.sub(startDate, frad.getFinReimDate()) + 1;
								//计划付息金额
								BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
								payIntAmt = payIntAmt.add(planPayIntAmt);
								PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, frad.getFinReimDate(), days, planPayIntAmt);
								detail.setTypes(types);
								detailList.add(detail);
								//重置起始日期
								startDate = DateUtils.add(frad.getFinReimDate(), Calendar.DATE, 1);
								//重置贷款余额
								loanAmt = loanAmt.subtract(frad.getFinReimAmt());
								types = PayIntDetTypeEnum.PAY_INT_DET_TYPE2.getCode();
							}
						}
						//计息天数
						int days = DateUtils.sub(startDate, endDate) + 1;
						if (days <= 0) continue;
						//计划付息金额=贷款余额*利率*计息天数/360
						BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
						payIntAmt = payIntAmt.add(planPayIntAmt);
						PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, endDate, days, planPayIntAmt);
						detail.setTypes(types);
						detailList.add(detail);
						//处理放款记录
						if (loanFinAmtList != null && loanFinAmtList.size() > 0) {
							for (LoanFinAmtDomain lfad : loanFinAmtList) {
								if (lfad == null) continue;
								PayInterestDetail pid = setDetailData(tdpi, hisLoanFinSumAmt, null, null, null, null, null);
								pid.setTypes(PayIntDetTypeEnum.PAY_INT_DET_TYPE3.getCode());
								detailList.add(pid);
							}
						}
						//新增主表数据
						payInterest.setPayIntAmt(payIntAmt);
						payInterestDao.insertSelective(payInterest);
						//新增子表数据
						for (PayInterestDetail tmpDetail : detailList) {
							if (tmpDetail == null) continue;
							tmpDetail.setPayInterestId(payInterest.getId());
							payInterestDetailDao.insertSelective(tmpDetail);
						}
						//发送OA待办
						String oaId = oaFlowService.sendOAToDo(tdpi.getProName(), tdpi.getAddBy(), tdpi.getAddBy(), TABLE_NAME, payInterest.getId(), tdpi.getProCode());
						payInterest.setOaId(oaId);
						payInterestDao.updateByIdSelective(payInterest);
					}
				} else if (StringUtils.equals(PayIntModeEnum.PAY_INT_MODE3.getCode(), tdpi.getPayIntMod())) {
					//半年
					Date maxDate = payInterestDao.queryMaxEndDate(tdpi.getProCode(), tdpi.getFinOrgId());
					if (maxDate != null) {
						tdpi.setBorrowDate(maxDate);
					}
					//判断时间是否满足季度3个月
					boolean isSend = checkMonth(tdpi.getBorrowDate(), endDate, 6);
					//判断截止日是否小于endDate，如果小于默认结清
					int tmpDay = DateUtils.sub(tdpi.getBorrowExpireDate(), endDate);
					if (tmpDay >= 0 || isSend) {
						//重设起始时间
						startDate = resetStartDate(startDate, tdpi.getBorrowDate());
						endDate = resetEndDate(endDate, tdpi.getBorrowExpireDate());
						//检查当月是否已经发送过待办
						int count = payInterestDetailDao.queryCountByIntDate(startDate, endDate);
						if (count > 0) {
							log.info(String.format("融资付息待办已发送，proCode：%s，finOrgId：%s，startDate：%s，endDate：%s", tdpi.getProCode(), tdpi.getFinOrgId(), DateUtils.dateParseShortString(startDate), DateUtils.dateParseShortString(endDate)));
							continue;
						}
						//查询历史放款总金额
						BigDecimal hisLoanFinSumAmt = payInterestDao.hisLoanFinSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisLoanFinSumAmt == null) hisLoanFinSumAmt = new BigDecimal(0);
						//查询历史还款总金额
						BigDecimal hisFinReimSumAmt = payInterestDao.hisFinReimSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisFinReimSumAmt == null) hisFinReimSumAmt = new BigDecimal(0);
						//贷款余额
						BigDecimal loanAmt = hisLoanFinSumAmt.subtract(hisFinReimSumAmt);
						//类型
						String types = PayIntDetTypeEnum.PAY_INT_DET_TYPE1.getCode();
						//付息金额-子表总和
						BigDecimal payIntAmt = new BigDecimal(0);
						//查询区间内是否有还款--startDate-endDate之间
						List<FinReimAmtDomain> finReimAmtList = payInterestDao.queryFinReimList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//查询区间内是否有放款--startDate-endDate之间
						List<LoanFinAmtDomain> loanFinAmtList = payInterestDao.queryLoanFinList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//处理还款记录
						if (finReimAmtList != null && finReimAmtList.size() > 0) {
							for (FinReimAmtDomain frad : finReimAmtList) {
								if (frad == null) continue;
								//根据还款日期计算截止时间
								//还款日期-起始日期=该段时间计息时间
								int days = DateUtils.sub(startDate, frad.getFinReimDate()) + 1;
								if (days <= 0) continue;
								//计划付息金额
								BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
								payIntAmt = payIntAmt.add(planPayIntAmt);
								PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, frad.getFinReimDate(), days, planPayIntAmt);
								detail.setTypes(types);
								detailList.add(detail);
								//重置起始日期
								startDate = DateUtils.add(frad.getFinReimDate(), Calendar.DATE, 1);
								//重置贷款余额
								loanAmt = loanAmt.subtract(frad.getFinReimAmt());
								types = PayIntDetTypeEnum.PAY_INT_DET_TYPE2.getCode();
							}
						}
						//计息天数
						int days = DateUtils.sub(startDate, endDate) + 1;
						if (days <= 0) continue;
						//计划付息金额=贷款余额*利率*计息天数/360
						BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
						payIntAmt = payIntAmt.add(planPayIntAmt);
						PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, endDate, days, planPayIntAmt);
						detail.setTypes(types);
						detailList.add(detail);
						//处理放款记录
						if (loanFinAmtList != null && loanFinAmtList.size() > 0) {
							for (LoanFinAmtDomain lfad : loanFinAmtList) {
								if (lfad == null) continue;
								PayInterestDetail pid = setDetailData(tdpi, hisLoanFinSumAmt, null, null, null, null, null);
								pid.setTypes(PayIntDetTypeEnum.PAY_INT_DET_TYPE3.getCode());
								detailList.add(pid);
							}
						}
						//新增主表数据
						payInterest.setPayIntAmt(payIntAmt);
						payInterestDao.insertSelective(payInterest);
						//新增子表数据
						for (PayInterestDetail tmpDetail : detailList) {
							if (tmpDetail == null) continue;
							tmpDetail.setPayInterestId(payInterest.getId());
							payInterestDetailDao.insertSelective(tmpDetail);
						}
						//发送OA待办
						String oaId = oaFlowService.sendOAToDo(tdpi.getProName(), tdpi.getAddBy(), tdpi.getAddBy(), TABLE_NAME, payInterest.getId(), tdpi.getProCode());
						payInterest.setOaId(oaId);
						payInterestDao.updateByIdSelective(payInterest);
					}
				} else if (StringUtils.equals(PayIntModeEnum.PAY_INT_MODE4.getCode(), tdpi.getPayIntMod())) {
					//年
					Date maxDate = payInterestDao.queryMaxEndDate(tdpi.getProCode(), tdpi.getFinOrgId());
					if (maxDate != null) {
						tdpi.setBorrowDate(maxDate);
					}
					//判断时间是否满足季度3个月
					boolean isSend = checkMonth(tdpi.getBorrowDate(), endDate, 12);
					//判断截止日是否小于endDate，如果小于默认结清
					int tmpDay = DateUtils.sub(tdpi.getBorrowExpireDate(), endDate);
					if (tmpDay >= 0 || isSend) {
						//重设起始时间
						startDate = resetStartDate(startDate, tdpi.getBorrowDate());
						endDate = resetEndDate(endDate, tdpi.getBorrowExpireDate());
						//检查当月是否已经发送过待办
						int count = payInterestDetailDao.queryCountByIntDate(startDate, endDate);
						if (count > 0) {
							log.info(String.format("融资付息待办已发送，proCode：%s，finOrgId：%s，startDate：%s，endDate：%s", tdpi.getProCode(), tdpi.getFinOrgId(), DateUtils.dateParseShortString(startDate), DateUtils.dateParseShortString(endDate)));
							continue;
						}
						//查询历史放款总金额
						BigDecimal hisLoanFinSumAmt = payInterestDao.hisLoanFinSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisLoanFinSumAmt == null) hisLoanFinSumAmt = new BigDecimal(0);
						//查询历史还款总金额
						BigDecimal hisFinReimSumAmt = payInterestDao.hisFinReimSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisFinReimSumAmt == null) hisFinReimSumAmt = new BigDecimal(0);
						//贷款余额
						BigDecimal loanAmt = hisLoanFinSumAmt.subtract(hisFinReimSumAmt);
						//类型
						String types = PayIntDetTypeEnum.PAY_INT_DET_TYPE1.getCode();
						//付息金额-子表总和
						BigDecimal payIntAmt = new BigDecimal(0);
						//查询区间内是否有还款--startDate-endDate之间
						List<FinReimAmtDomain> finReimAmtList = payInterestDao.queryFinReimList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//查询区间内是否有放款--startDate-endDate之间
						List<LoanFinAmtDomain> loanFinAmtList = payInterestDao.queryLoanFinList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//处理还款记录
						if (finReimAmtList != null && finReimAmtList.size() > 0) {
							for (FinReimAmtDomain frad : finReimAmtList) {
								if (frad == null) continue;
								//根据还款日期计算截止时间
								//还款日期-起始日期=该段时间计息时间
								int days = DateUtils.sub(startDate, frad.getFinReimDate()) + 1;
								if (days <= 0) continue;
								//计划付息金额
								BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
								payIntAmt = payIntAmt.add(planPayIntAmt);
								PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, frad.getFinReimDate(), days, planPayIntAmt);
								detail.setTypes(types);
								detailList.add(detail);
								//重置起始日期
								startDate = DateUtils.add(frad.getFinReimDate(), Calendar.DATE, 1);
								//重置贷款余额
								loanAmt = loanAmt.subtract(frad.getFinReimAmt());
								types = PayIntDetTypeEnum.PAY_INT_DET_TYPE2.getCode();
							}
						}
						//计息天数
						int days = DateUtils.sub(startDate, endDate) + 1;
						if (days <= 0) continue;
						//计划付息金额=贷款余额*利率*计息天数/360
						BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
						payIntAmt = payIntAmt.add(planPayIntAmt);
						PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, endDate, days, planPayIntAmt);
						detail.setTypes(types);
						detailList.add(detail);
						//处理放款记录
						if (loanFinAmtList != null && loanFinAmtList.size() > 0) {
							for (LoanFinAmtDomain lfad : loanFinAmtList) {
								if (lfad == null) continue;
								PayInterestDetail pid = setDetailData(tdpi, hisLoanFinSumAmt, null, null, null, null, null);
								pid.setTypes(PayIntDetTypeEnum.PAY_INT_DET_TYPE3.getCode());
								detailList.add(pid);
							}
						}
						//新增主表数据
						payInterest.setPayIntAmt(payIntAmt);
						payInterestDao.insertSelective(payInterest);
						//新增子表数据
						for (PayInterestDetail tmpDetail : detailList) {
							if (tmpDetail == null) continue;
							tmpDetail.setPayInterestId(payInterest.getId());
							payInterestDetailDao.insertSelective(tmpDetail);
						}
						//发送OA待办
						String oaId = oaFlowService.sendOAToDo(tdpi.getProName(), tdpi.getAddBy(), tdpi.getAddBy(), TABLE_NAME, payInterest.getId(), tdpi.getProCode());
						payInterest.setOaId(oaId);
						payInterestDao.updateByIdSelective(payInterest);
					}
				} else if (StringUtils.equals(PayIntModeEnum.PAY_INT_MODE5.getCode(), tdpi.getPayIntMod())) {
					//到期一次性付
					//判断截止日是否小于等于endDate，小于等于直接一次性结清
					int tmpDay = DateUtils.sub(tdpi.getBorrowExpireDate(), endDate);
					if (tmpDay >= 0) {
						//重设起始时间
						startDate = resetStartDate(startDate, tdpi.getBorrowDate());
						endDate = resetEndDate(endDate, tdpi.getBorrowExpireDate());
						//检查当月是否已经发送过待办
						int count = payInterestDetailDao.queryCountByIntDate(startDate, endDate);
						if (count > 0) {
							log.info(String.format("融资付息待办已发送，proCode：%s，finOrgId：%s，startDate：%s，endDate：%s", tdpi.getProCode(), tdpi.getFinOrgId(), DateUtils.dateParseShortString(startDate), DateUtils.dateParseShortString(endDate)));
							continue;
						}
						//查询历史放款总金额
						BigDecimal hisLoanFinSumAmt = payInterestDao.hisLoanFinSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisLoanFinSumAmt == null) hisLoanFinSumAmt = new BigDecimal(0);
						//查询历史还款总金额
						BigDecimal hisFinReimSumAmt = payInterestDao.hisFinReimSumAmt(tdpi.getProCode(), tdpi.getFinOrgId(), startDate);
						if (hisFinReimSumAmt == null) hisFinReimSumAmt = new BigDecimal(0);
						//贷款余额
						BigDecimal loanAmt = hisLoanFinSumAmt.subtract(hisFinReimSumAmt);
						//类型
						String types = PayIntDetTypeEnum.PAY_INT_DET_TYPE1.getCode();
						//付息金额-子表总和
						BigDecimal payIntAmt = new BigDecimal(0);
						//查询区间内是否有还款--startDate-endDate之间
						List<FinReimAmtDomain> finReimAmtList = payInterestDao.queryFinReimList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//查询区间内是否有放款--startDate-endDate之间
						List<LoanFinAmtDomain> loanFinAmtList = payInterestDao.queryLoanFinList(tdpi.getProCode(), tdpi.getFinOrgId(), startDate, endDate);
						//处理还款记录
						if (finReimAmtList != null && finReimAmtList.size() > 0) {
							for (FinReimAmtDomain frad : finReimAmtList) {
								if (frad == null) continue;
								//根据还款日期计算截止时间
								//还款日期-起始日期=该段时间计息时间
								int days = DateUtils.sub(startDate, frad.getFinReimDate()) + 1;
								if (days <= 0) continue;
								//计划付息金额
								BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
								payIntAmt = payIntAmt.add(planPayIntAmt);
								PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, frad.getFinReimDate(), days, planPayIntAmt);
								detail.setTypes(types);
								detailList.add(detail);
								//重置起始日期
								startDate = DateUtils.add(frad.getFinReimDate(), Calendar.DATE, 1);
								//重置贷款余额
								loanAmt = loanAmt.subtract(frad.getFinReimAmt());
								types = PayIntDetTypeEnum.PAY_INT_DET_TYPE2.getCode();
							}
						}
						//计息天数
						int days = DateUtils.sub(startDate, endDate) + 1;
						if (days <= 0) continue;
						//计划付息金额=贷款余额*利率*计息天数/360
						BigDecimal planPayIntAmt = loanAmt.multiply(tdpi.getInterestRate()).multiply(new BigDecimal(days)).divide(new BigDecimal((100 * 360)), 2, BigDecimal.ROUND_HALF_UP);
						payIntAmt = payIntAmt.add(planPayIntAmt);
						PayInterestDetail detail = setDetailData(tdpi, hisLoanFinSumAmt, loanAmt, startDate, endDate, days, planPayIntAmt);
						detail.setTypes(types);
						detailList.add(detail);
						//处理放款记录
						if (loanFinAmtList != null && loanFinAmtList.size() > 0) {
							for (LoanFinAmtDomain lfad : loanFinAmtList) {
								if (lfad == null) continue;
								PayInterestDetail pid = setDetailData(tdpi, hisLoanFinSumAmt, null, null, null, null, null);
								pid.setTypes(PayIntDetTypeEnum.PAY_INT_DET_TYPE3.getCode());
								detailList.add(pid);
							}
						}
						//新增主表数据
						payInterest.setPayIntAmt(payIntAmt);
						payInterestDao.insertSelective(payInterest);
						//新增子表数据
						for (PayInterestDetail tmpDetail : detailList) {
							if (tmpDetail == null) continue;
							tmpDetail.setPayInterestId(payInterest.getId());
							payInterestDetailDao.insertSelective(tmpDetail);
						}
						//发送OA待办
						String oaId = oaFlowService.sendOAToDo(tdpi.getProName(), tdpi.getAddBy(), tdpi.getAddBy(), TABLE_NAME, payInterest.getId(), tdpi.getProCode());
						payInterest.setOaId(oaId);
						payInterestDao.updateByIdSelective(payInterest);
					}
				}
			}
		}
	}

	/**
	 * 重设开始时间
	 * @param startDate
	 * @param tmpDate
	 * @return
	 */
	private Date resetStartDate(Date startDate, Date tmpDate) {
		//如果tmpDate大于startDate，默认从tmpDate开始计息
		int days = DateUtils.sub(startDate, tmpDate);
		if (days > 0) return tmpDate;
		return startDate;
	}

	/**
	 * 重设截止日期
	 * @param endDate
	 * @param tmpDate
	 * @return
	 */
	private Date resetEndDate(Date endDate, Date tmpDate) {
		//如果endDate大于tmpDate，默认计息截止日为tmpDate
		int days = DateUtils.sub(tmpDate, endDate);
		if (days > 0) return tmpDate;
		return endDate;
	}

	/**
	 * 检查两个时间间隔月份
	 * @param startDate
	 * @param endDate
	 * @param months
	 * @return
	 */
	private boolean checkMonth(Date startDate, Date endDate, int months) {
		Calendar startCal = Calendar.getInstance();
		startCal.setTime(startDate);
		//获取起始月份和月份，如果天数小于等于20，月份数量多一个月，月份起始时间是当月21号-次月20号截止
		int startYear = startCal.get(Calendar.YEAR);
		int startMonth = startCal.get(Calendar.MONTH);
		if (startCal.get(Calendar.DATE) <= 20) startMonth--;
		Calendar endCal = Calendar.getInstance();
		endCal.setTime(endDate);
		endCal.add(Calendar.MONTH, -months);
		int endYear = endCal.get(Calendar.DATE);
		int endMonth = endCal.get(Calendar.MONTH);
		if (startYear == endYear && startMonth == endMonth) return true;
		return false;
	}

	private PayInterestDetail setDetailData(ToDoPayIntDomain tdpi, BigDecimal hisLoanFinSumAmt, BigDecimal loanAmt,
											Date startDate, Date endDate, Integer days, BigDecimal planPayIntAmt) {
		PayInterestDetail detail = new PayInterestDetail();
		detail.setContractName(tdpi.getProName());
		detail.setFinanceOrgName(tdpi.getDockName());
		detail.setLoanAmt(hisLoanFinSumAmt);
		detail.setCompCost(tdpi.getEmbeddedCost());
		detail.setLoanBalance(loanAmt);
		detail.setIntRate(tdpi.getInterestRate());
		detail.setAddBy(tdpi.getAddBy());
		detail.setAddTime(new Date());
		detail.setUptBy(tdpi.getAddBy());
		detail.setUptTime(new Date());
		//计息开始日期
		detail.setIntBeginDate(startDate);
		//计息结束日期
		detail.setIntEndDate(endDate);
		//计息天数
		if (days == null) {
			detail.setIntCountDay(null);
		} else {
			detail.setIntCountDay(new BigDecimal(days));
		}
		//计划付息金额
		detail.setPlanPayIntAmt(planPayIntAmt);
		return detail;
	}
}